from django.utils.decorators import method_decorator
from django.utils.deprecation import MiddlewareMixin
from mydjango.settings import SECRET_KEY
from qiniu import Auth
from django.shortcuts import render, redirect
# 导包
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
# 导入类视图

from django.views import View

# from myapp.models import User
import json
from django.core.serializers import serialize
from rest_framework.response import Response
from rest_framework.views import APIView
# 导入加密库
import hashlib
# 导入图片库
# 绘画库
from PIL import ImageDraw
# 字体库
from PIL import ImageFont
# 图片库
from PIL import Image
# 随机库
import random
# 文件流
import io

import requests

# 导入上传文件夹配置
from mydjango.settings import UPLOAD_ROOT
import os

# 导入原生sql模块
from django.db import connection

import jwt

# 导入redis数据库
import redis

# 导入时间模块
import time

# 导入公共目录变量
from mydjango.settings import BASE_DIR

# 导包
from django.db.models import Q, F

# 导入dwebsocket的库
from dwebsocket.decorators import accept_websocket
import uuid
from myapp.models import User
import redis
import base64
from hashlib import sha256
import hmac
import urllib
import re
from myapp.myser import UserSer

# IP和端口

host = 'localhost'
port = 6379

# host = '192.168.99.100'
# port = 6380

# 链接对象
r = redis.Redis(host=host, port=port)


class UserList(APIView):
    
    def get(self, request):
        user = User.objects.all()
        user_ser = UserSer(user, many=True)
        return Response(user_ser.data)
        


class MyMiddleWare(MiddlewareMixin):  # 自定义中间件
    def process_request(self, request):
        # uid = request.GET.get('uid')
        # clinet_jwt = request.GET.get('jwt')
        # if clinet_jwt == None:
        #     return HttpResponse('令牌不足')
        # decode_jwt = jwt.decode(clinet_jwt, SECRET_KEY, algorithms=['HS256'])
        # if decode_jwt['uid'] != str(uid):
        #     return HttpResponse('你篡改了用户ID')
        pass

    # def process_response(self, response, request):
    #     pass

    def process_view(self, request, view_func, view_args, view_kwargs):
        pass


def my_decorator(func):  # 装饰器
    def wrapper(request, *args, **kwargs):
        # print('这个装饰器被调用了')
        # print('请求地址为%s' % request.path)
        # uid = request.GET.get('uid')
        # clinet_jwt = request.GET.get('jwt')
        # if clinet_jwt == None:
        #     return HttpResponse('令牌不足')
        # decode_jwt = jwt.decode(clinet_jwt, SECRET_KEY, algorithms=['HS256'])
        # if decode_jwt['uid'] != str(uid):
        #     return HttpResponse('你篡改了用户ID')
        return func(request, *args, **kwargs)

    return wrapper


# 类装饰器调用
class UserInfo(APIView):  # 序列化 用户的数据
    @method_decorator(my_decorator)
    def get(self, request):
        uid = request.GET.get('uid')
        user = User.objects.get(id=uid)
        user_ser = UserSer(user)
        return Response(user_ser.data)


class Add_image(APIView):
    def get(self, request):
        uid = request.GET.get('uid')
        image = request.GET.get('image')
        User.objects.filter(id=uid).update(image=image)
        return Response({
            'code': 200,
            'data': '视频添加成功'
        })


class QiNiu(APIView):  # 定义七牛云存储接口
    def get(self, request):
        # 定义密钥
        q = Auth('UYGbfDgXLrBGi420P1TxxkegKFuN--NM3wEWymjK',
                 'kxDalUpo9-eclSfWT69xtuqdgdoQenjiOXZ3rzAQ')
        token = q.upload_token('uploadxiaobai')  # 指定上传空间
        # print(token)  # 打印一下返回值
        return Response({
            'code': 200,
            'token': token
        })


# 修改用户密码
class UpdateUserAPIView(APIView):
    def get(self, request):
        uid = request.GET.get('uid')
        password = request.GET.get('password')
        User.objects.filter(id=uid).update(password=make_password(password))
        return Response({
            'code': 200,
            'data': '修改成功'
        })


# 上传头像图片
class UploadFile(View):
    def post(self, request):
        # 接收参数
        qiniu = request.POST.get('qiniu')
        # 获取用户信息
        uid = request.POST.get('uid')
        user = User.objects.filter(id=uid).first()
        if qiniu:
            qiniu_imgname = request.POST.get('qiniu_name')
            user.img = qiniu_imgname
            user.save()
            return HttpResponse(json.dumps({
                'code': 200,
                'data': '图片名已保存'
            }))
        img = request.FILES.get('file')
        imagename = img.name
        # 建立文件流对象
        f = open(os.path.join(UPLOAD_ROOT, '', img.name), 'wb')
        # 写入
        for chunk in img.chunks():
            f.write(chunk)
        f.close()
        img = Image.open('./static/upload/' + img.name)
        draw = ImageDraw.Draw(img)
        my_font = ImageFont.truetype(
            font='C:\\Windows\\Fonts\\FZSTK.TTF', size=35)
        draw.text((0, 0), '用户' + user.username,
                  fill=(152, 254, 255), font=my_font)
        # img.show()
        img.save('./static/upload/' + imagename)
        # 获取图片后缀
        newimgename = user.username + \
            re.findall(r'(.jpg|.png|.JPEG)', imagename)[0]
        # 删除旧图
        try:
            os.remove(UPLOAD_ROOT + '\\' + newimgename)
        except Exception as e:
            print(e)
        # 修改图片名称
        os.rename(UPLOAD_ROOT + '\\' + imagename,
                  UPLOAD_ROOT + '\\' + newimgename)
        # 将图片名保存到库中
        user.img = newimgename
        user.save()

        # 返回文件名
        return HttpResponse(json.dumps({'filename': newimgename}, ensure_ascii=False), content_type='application/json')


# 钉钉回调
def ding_back(request):
    code = request.GET.get('code')
    t = time.time()
    # 时间戳
    timestamp = str((int(round(t * 1000))))
    appSecret = 'kFeBIcAi-P5VNeA_2EIjARQu6dYct2h-3iiTUNpPEBuWjN3efumu2BfLhBgGVttz'
    # 构造签名
    signature = base64.b64encode(
        hmac.new(appSecret.encode('utf-8'), timestamp.encode('utf-8'), digestmod=sha256).digest())
    # 请求接口，换取钉钉用户名
    payload = {'tmp_auth_code': code}
    headers = {'Content-Type': 'application/json'}
    res = requests.post('https://oapi.dingtalk.com/sns/getuserinfo_bycode?signature=' + urllib.parse.quote(
        signature.decode("utf-8")) + "&timestamp=" + timestamp + "&accessKey=dingoaty1hbauyiitjsip2",
        data=json.dumps(payload), headers=headers)

    res_dict = json.loads(res.text)
    user = User.objects.filter(username=str(
        res_dict['user_info']['nick'])).first()
    dingding_id = ''
    user_id = ''
    if user:
        dingding_id = res_dict['user_info']['nick']
        user_id = user.id
    else:
        User.objects.create(username=str(
            res_dict['user_info']['nick']), password='')
        user = User.objects.filter(username=str(
            res_dict['user_info']['nick'])).first()
        dingding_id = res_dict['user_info']['nick']
        user_id = user.id

    return redirect('http://localhost:8080/?dingding_id=' + str(dingding_id) + '&' + 'uid=' + str(user_id))


# 新浪微博回调
def wb_back(request):
    # 获取code
    code = request.GET.get('code')
    # 定义微博认证地址
    data = {
        'client_id': '297351690',
        'client_secret': '8e24e86fd5dfa8d95675316bd969f9f1',
        'grant_type': 'authorization_code',
        'code': code,
        'redirect_uri': 'http://127.0.0.1:8000/weibo_callback'
    }
    url = 'https://api.weibo.com/oauth2/access_token'

    res = requests.post(url, data=data).text
    res = json.loads(res)
    # return HttpResponse(res['uid'])

    # 获取新浪微博用户名
    result = requests.get(url='https://api.weibo.com/2/users/show.json',
                          params={'access_token': res['access_token'], 'uid': res['uid']})
    result = json.loads(result.text)
    # print(result)

    # 判断该用户曾经是否登陆过
    user = User.objects.filter(username=str(result['name'])).first()
    sina_id = ''
    user_id = ''

    if user:
        sina_id = user.username
        user_id = user.id
    else:
        # 手动创建账号
        User.objects.create(username=str(result['name']), password='')
        sina_id = result['name']
        user = User.objects.filter(username=str(result['name'])).first()
        user_id = user.id
    print(user_id)
    return redirect('http://localhost:8080/?sina_id=' + str(sina_id) + '&user_id=' + str(user_id))


# 登陆接口
class Login(APIView):
    def get(self, request):
        username = request.GET.get('username')  # 获取前端传过来的username数据
        password = request.GET.get('password')  # 获取密码

        # 查询数据
        user = User.objects.filter(
            username=username, password=make_password(password)).first()
        if user:
            encode_jwt = jwt.encode({'uid': str(user.id)}, SECRET_KEY, algorithm='HS256')
            encode_str = str(encode_jwt, 'utf-8')
            return Response({
                'uid': user.id,
                'username': user.username,
                'code': 200,
                'data': '登陆成功',
                # 加入jwt令牌机制
                'jwt': encode_str,
                'type': user.type
            })
        else:
            return Response({
                'code': 405,
                'data': '用户名或者密码错误'
            })


# 验证码类
class MyCode(View):
    # 定义随机颜色
    def get_random_color(self):
        R = random.randrange(200)
        G = random.randrange(200)
        B = random.randrange(200)

        return (R, G, B)

    # def get_random_color_img(self):
    #     R = random.randrange(200, 255)
    #     G = random.randrange(200, 255)
    #     B = random.randrange(200, 255)
    #     return (R, G, B)

    # 获取验证码视图
    def get(self, request):
        # 画布
        img_size = (150, 60)  # 定义验证码画布的大小
        # 定义画图对象
        image = Image.new('RGB', img_size, 'white')  # white 为画布背景颜色
        # 定义画笔对象
        draw = ImageDraw.Draw(image, 'RGB')
        # 定义随机字符串
        source = 'abcdefg12678今天天气不错HelloWor验证码画布背景颜色RGB'
        # 容器
        code_str = ''
        # 定义字体
        my_font = ImageFont.truetype(font='C:\\Windows\\Fonts\\FZSTK.TTF', size=17)
        for i in range(4):
            # 获取随机颜色
            text_color = self.get_random_color()  # 调用get_random_color方法
            # 获取随机字符串的下标
            tmp_num = random.randrange(len(source))
            # 获取字符集(根据下标获取对应字符)
            random_str = source[tmp_num]
            # 添加到容器中
            code_str += random_str
            # 将字符串添加到画布上
            draw.text((10 + 30 * i, 20), random_str, text_color, font=my_font)  # font 定义字体
        # 建立缓存区
        buf = io.BytesIO()  # 在内存中开辟一小块空间

        # 将验证码存储到Redis中
        r.set('code', code_str)

        # Session存储
        # request.session['code'] = code_str

        # print(request.session.get('code'),'session保存的值')

        # 保存图片
        image.save(buf, 'png')
        return HttpResponse(buf.getvalue(), 'image/png')


# 方法视图
def myindex(request):
    return HttpResponse('这里是首页')


def make_password(mypwd):
    md5 = hashlib.md5()  # 生成md5
    sign_str = str(mypwd)  # 定义机密对象
    sign_utf8 = sign_str.encode(encoding='utf-8')  # 转码
    md5.update(sign_utf8)  # 加密
    md5_sever = md5.hexdigest()  # 生成密钥串

    return md5_sever


# 注册
class RegisterView(APIView):

    def get(self, request):
        username = request.GET.get('username', 'null')
        password = request.GET.get('password')
        code = request.GET.get('code')
        # print(code,'获取前端code的值')
        if code:
            git_code = r.get('code').decode('utf-8')
            # ssession_code = request.session.get('code')
            # print(ssession_code,'注册提取的时候')
            if not git_code == code:
                return Response({
                    'code': 405,
                    'data': '验证码错误'
                })
        else:
            return Response({
                'code': 405,
                'data': '验证码为空,请输入验证码'
            })

        if User.objects.filter(username=username):
            return Response({
                'code': 405,
                'data': '用户已存在'
            })
        else:
            User.objects.create(username=username,
                                password=make_password(password))
            return Response({
                'code': 200,
                'data': '注册成功'
            })

# class MyView(View):
#     def get(self, request):
#         userlist = []
#         users = User.objects.filter().all()
#         for user in users:
#             userlist.append({
#                 'id': user.id,
#                 'username': user.username,
#                 'password': user.password,
#                 'img': user.img,
#                 'datetime': user.create_time
#             })
#
#         return render(request, 'index.html', locals())
#
#     def post(self, request):
#         deluser = request.POST.get('del')
#         username = request.POST.get('name')
#         password = request.POST.get('password')
#         type = request.POST.get('type')
#         if deluser:
#             User.objects.filter(id=request.POST.get('del')).delete()
#         elif username:
#             User.objects.create(username=username, password=password, type=type)
#         else:
#             id = request.POST.get('upd')
#             if id:
#                 return redirect('http://127.0.0.1:8000/upd?id=' + id)
#
#         return redirect('http://127.0.0.1:8000/')
#
#
# class UpdUser(View):
#     def get(self, request):
#         id = request.GET.get('id')
#         user = User.objects.filter(id=id).first()
#
#         id = user.id
#         username = user.username
#         password = user.password
#         type = user.type
#         create_time = user.create_time
#
#         return render(request, 'update.html', locals())
#
#     def post(self, request):
#         id = request.POST.get('id')
#         username = request.POST.get('username')
#         password = request.POST.get('password')
#         type = request.POST.get('type')
#         # print(id, username, password, type)
#
#         user = User.objects.filter(id=id).update(username=username, password=password, type=int(type))
#         if user:
#             return redirect('http://127.0.0.1:8000/')
#         else:
#             return redirect('http://127.0.0.1:8000/')
